package engine;

import java.util.ArrayList;
import java.util.List;
import java.io.*;

import quadTree.BoundingBox;
public class SceneFile {
	private ArrayList<String> state;
	static int saveSlot = 0;

	/**
	 * SceneFile Constructor
	 */
	public SceneFile() {
		state = new ArrayList<String>();
	}
	
	/**
	 * writeScene writes the Scene in, its current state, to a user specified file.  If the filename is invalid, it will default to Scene.txt
	 * @param fileName the user specified filename
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns \nothing;
	 */
	public void writeScene(String fileName)
	{
		if(fileName==null||fileName.length()<=0||fileName.length()>32)
		{
			int x = ++saveSlot;
			fileName = "Scene" + x + ".txt";
		}
		File file;
		try {
			file = new File(fileName);
			
			boolean success = file.createNewFile();
			if(success) {
				//File created successfully
			}
			else {
				file.delete();
				file.createNewFile();
			}
		}
		catch(IOException e) {
			System.err.println("Error in creating new file\n");
			return;
		}
	//and cycling through all objects, forces, structures...


	{
		try {
		    BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true));
		    out.write(state.toString());
		    out.close();
			} 
		catch (IOException e) {
			System.err.println(e.getMessage());
		}
	
	}	
	}
	/**
	 * addToBuffer adds a string to the string describing the SceneFile's state
	 * @param s the string to be appended to the scene's state
	 */
	/*
	 * @requires s != null;
	 */
	public void addToBuffer(String s)
	{
		state.add(s);
	}
	/**
	 * LoadScene loads a Scene from a file
	 * @param filename the Scene to be loaded
	 * @return the newly reconstituted scene
	 */
	public Scene LoadScene(String filename) {
		try {
			FileInputStream fstream = new FileInputStream(filename);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
			String strLine;
			Scene s = new Scene(1f);
			while((strLine = buffer.readLine()) != null) {
				if (strLine.contains("Bounding Box:")){
					strLine = buffer.readLine();
					String[] points = strLine.split(",");
					Vector UL = new Vector(Float.valueOf(points[0].split(":")[1]), Float.valueOf(points[1]));
					strLine = buffer.readLine();
					points = strLine.split(",");
					Vector LR = new Vector(Float.valueOf(points[0].split(":")[1]), Float.valueOf(points[1]));
					BoundingBox box = new BoundingBox(UL, LR);
					s = new Scene(box);
				}
				else if(strLine.contains("Physics Objects")) {
					while((strLine = buffer.readLine()).contains("Object")) {
						strLine = buffer.readLine();
						String temp = strLine;
						int index = Integer.valueOf(temp.split("Mass")[0].split("Index")[1]);
						temp = strLine;
						float mass = Float.valueOf(temp.split("Velocity")[0].split("Mass")[1]);
						temp = strLine;
						String Velocity = temp.split("Velocity")[1].split("Position")[0];
						Vector velo = new Vector(Float.valueOf(Velocity.split(",")[0]),Float.valueOf(Velocity.split(",")[1]));
						temp = strLine;
						String Position = temp.split("Position")[1].split("Angle")[0];
						Vector pos = new Vector(Float.valueOf(Position.split(",")[0]),Float.valueOf(Position.split(",")[1]));
						temp = strLine;
						String Angle = temp.split("Angle")[1].split("AngVelo")[0];
						float ang = Float.valueOf(Angle);
						temp = strLine;
						String AngVelo = temp.split("AngVelo")[1].split("Inertia")[0];
						float angVelo = Float.valueOf(AngVelo);
						temp = strLine;
						String Inertia = temp.split("Inertia")[1];
						float inertia = Float.valueOf(Inertia);
						strLine = buffer.readLine();
						ArrayList<Vertex> verts = new ArrayList<Vertex>();
						ArrayList<Edge> edges = new ArrayList<Edge>();
						if(strLine.contains("Edges:")) {
							while((strLine = buffer.readLine()).contains("Edge")) {
								strLine = buffer.readLine();
								temp = strLine;
								String v1 = temp.split("and")[0].split("between")[1];
								Vector vpos = new Vector(Float.valueOf(v1.split(",")[0]),Float.valueOf(v1.split(",")[1]));
								Vertex vert1 = new Vertex(vpos);
								
								temp = strLine;
								String v2 = temp.split("with")[0].split("and")[1];
								vpos = new Vector(Float.valueOf(v2.split(",")[0]),Float.valueOf(v2.split(",")[1]));
								Vertex vert2 = new Vertex(vpos);
								
								temp = strLine;
								String Weight = temp.split("weight")[1];
								float weight = Float.valueOf(Weight);
								Edge e = new Edge(vert1, vert2, weight);
								edges.add(e);
								if(!verts.contains(vert1)) {
									verts.add(vert1);
								}
								if(!verts.contains(vert2)) {
									verts.add(vert2);
								}
							}
						}
						PhysicsObject po = new PhysicsObject(index, verts, mass, edges, velo);
						po.setEdges(edges);
						po.setAngle(ang);
						po.setAngularVelo(angVelo);
						po.setInertiaTensor(inertia);
						s.addObject(po);
						
					}
				}
				else if (strLine.contains("Forces:")){
					while((strLine = buffer.readLine()).contains("Force")) {
						String temp = strLine;
						float range = Float.valueOf(temp.split("at")[0].split("Range")[1]);
						temp = strLine;
						String Position = temp.split("with")[0].split("at")[1];
						Vector pos = new Vector(Float.valueOf(Position.split(",")[0]),Float.valueOf(Position.split(",")[1]));
						temp = strLine;
						String Direction = temp.split("direction")[1];
						Vector dir = new Vector(Float.valueOf(Direction.split(",")[0]),Float.valueOf(Direction.split(",")[1]));
						Force f = new Force(pos, dir, range);
						s.addForce(f);	
					}
				}
			}
			return s;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return new Scene(1f);
	}
}
